/* eslint-disable no-unused-vars */
import dispatch from "./dispatch";
import RequestInterceptor, {
  ResolvedFn,
  RejectedFn,
} from "./requestInterceptor";

export interface IDefaultOptions {
  baseUrl: string;
  headers: {
    [key: string]: string;
  };
  timeout: number;
}

export type TMethod = "GET" | "POST" | "PUT" | "DELETE";

export interface ISendConfig extends Partial<IDefaultOptions> {
  data?: any;
  url: string;
  method: TMethod;
  loading?: Boolean;
  loadingText?: string;
  needToken?: Boolean;
  requests?: Array<IPromiseChain>;
  responses?: Array<IPromiseChain>;
}

interface ITnterceptor {
  request: RequestInterceptor<ISendConfig>;
  response: RequestInterceptor<any>;
}

interface IPromiseChain {
  resolved: ResolvedFn;
  rejected?: RejectedFn | null;
}

class xjwRequest {
  public defaultOptions: Partial<IDefaultOptions> = {
    baseUrl: "",
    headers: {
      //   "content-type": "application/json;charset=UTF-8",
      "content-type": "application/x-www-form-urlencoded",
    },
    timeout: 3000,
  };

  public interceptors: ITnterceptor;
  public defaultConfig: ISendConfig = {
    data: {},
    url: "",
    method: "POST",
    loading: true,
    loadingText: "加载中.",
    needToken: true,
    requests: [],
    responses: [],
  };

  constructor(options: Partial<IDefaultOptions>) {
    Object.assign(this.defaultOptions, options);
    this.interceptors = {
      request: new RequestInterceptor(),
      response: new RequestInterceptor(),
    };
  }

  request(config: ISendConfig): Promise<any> {
    console.log("================>> network:",config.url,config);
    const chain: Array<IPromiseChain> = [
      {
        resolved: dispatch,
        rejected: null,
      },
    ];

    const megerOptions = Object.assign(
      {},
      this.defaultOptions,
      this.defaultConfig,
      config
    );
    let promise = Promise.resolve(megerOptions);

    megerOptions.requests?.forEach((interceptor) => {
      chain.unshift(interceptor);
    });

    this.interceptors.request.forEach((interceptor) => {
      chain.unshift(interceptor);
    });

    this.interceptors.response.forEach((interceptor) => {
      chain.push(interceptor);
    });

    megerOptions.responses?.forEach((interceptor) => {
      chain.push(interceptor);
    });

    while (chain.length) {
      const { resolved, rejected } = chain.shift()!;
      promise = promise.then(resolved, rejected);
    }
    return promise;
  }
}

export default xjwRequest;
